package org.quipu.dto;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class TransactionsFilterDto implements Serializable {
/*
    public enum OrderAttribute {
        DATE(null);

        private final Long attributeId;

        public OrderAttribute(Long attributeId) {
            this.attributeId = attributeId;
        }

        public Long getAttributeId() {
            return attributeId;
        }
    };*/

    public enum Order {
        ASC,
        DESC
    };

    public static class AccountsInfo implements Serializable {

        private Long srcAccountId;
        private Long dstAccountId;

        public Long getSrcAccountId() {
            return srcAccountId;
        }

        public void setSrcAccountId(Long srcAccountId) {
            this.srcAccountId = srcAccountId;
        }

        public Long getDstAccountId() {
            return dstAccountId;
        }

        public void setDstAccountId(Long dstAccountId) {
            this.dstAccountId = dstAccountId;
        }
    }

    private boolean incomes;
    private boolean outcomes;
    private boolean transfers;
    private LinkedList<AccountsInfo> accountsInfo;
    private Date dateFrom;
    private Date dateTo;
    private Map<CategoryDto.Type, LinkedList<Long>> categoryIds;
    private LinkedList<Long> tagIds;
    private boolean approvedOnly;
    private Order order;

    public TransactionsFilterDto() {
        accountsInfo = new LinkedList<AccountsInfo>();
        categoryIds = new EnumMap<CategoryDto.Type, LinkedList<Long>>(CategoryDto.Type.class);
        categoryIds.put(CategoryDto.Type.INCOME, new LinkedList<Long>());
        categoryIds.put(CategoryDto.Type.OUTCOME, new LinkedList<Long>());
        tagIds = new LinkedList<Long>();
        order = Order.DESC;
    }

    public Date getDateFrom() {
        return dateFrom;
    }

    public void setDateFrom(Date dateFrom) {
        this.dateFrom = dateFrom;
    }

    public Date getDateTo() {
        return dateTo;
    }

    public void setDateTo(Date dateTo) {
        this.dateTo = dateTo;
    }

    public boolean isIncomes() {
        return incomes;
    }

    public void setIncomes(boolean incomes) {
        this.incomes = incomes;
    }

    public boolean isOutcomes() {
        return outcomes;
    }

    public void setOutcomes(boolean outcomes) {
        this.outcomes = outcomes;
    }

    public boolean isTransfers() {
        return transfers;
    }

    public void setTransfers(boolean transfers) {
        this.transfers = transfers;
    }

    public boolean isApprovedOnly() {
        return approvedOnly;
    }

    public void setApprovedOnly(boolean approvedOnly) {
        this.approvedOnly = approvedOnly;
    }

    public List<AccountsInfo> getAccountsInfo() {
        return accountsInfo;
    }

    public void clearAccountsInfo() {
        accountsInfo.clear();
    }

    public void addAccountInfo(AccountsInfo accountsInfo) {
        this.accountsInfo.add(accountsInfo);
    }

    public void addAccountInfo(Collection<AccountsInfo> accountsInfo) {
        this.accountsInfo.addAll(accountsInfo);
    }

    public void setAccountInfo(Collection<AccountsInfo> accountsInfo) {
        clearAccountsInfo();
        addAccountInfo(accountsInfo);
    }

    public List<Long> getCategoryIds(CategoryDto.Type type) {
        return categoryIds.get(type);
    }

    public void clearCategoryIds(CategoryDto.Type type) {
        categoryIds.get(type).clear();
    }

    public void addCategoryId(CategoryDto.Type type, Long categoryId) {
        categoryIds.get(type).add(categoryId);
    }

    public void addCategoryIds(CategoryDto.Type type, Collection<Long> categoryIds) {
        this.categoryIds.get(type).addAll(categoryIds);
    }

    public void setCategoryIds(CategoryDto.Type type, Collection<Long> categoryIds) {
        clearCategoryIds(type);
        addCategoryIds(type, categoryIds);
    }

    public List<Long> getTagIds() {
        return tagIds;
    }

    public void clearTagIds() {
        tagIds.clear();
    }

    public void addTagId(Long tagId) {
        tagIds.add(tagId);
    }

    public void addTagIds(Collection<Long> tagIds) {
        this.tagIds.addAll(tagIds);
    }

    public void addTags(Collection<TagDto> tags) {
        for(TagDto tag: tags) {
            tagIds.add(tag.getId());
        }
    }

    public void setTagIds(Collection<Long> tagIds) {
        clearTagIds();
        addTagIds(tagIds);
    }

    public void setTags(Collection<TagDto> tags) {
        clearTagIds();
        addTags(tags);
    }

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }
}
